//
//  MKAPIRequestParam.m
//  MKAPI
//
//  Created by 苏尚进 on 2022/9/6.
//  Copyright © 2022 moon. All rights reserved.
//

#import "MKAPIRequestParam.h"
#import "NSObject+MKAPI.h"
@interface MKAPIRequestParam ()
@property(nonatomic,strong) MKAPIDictionary *headersParam;
@end

@implementation MKAPIRequestParam
- (id)init{
    if (self=[super init]) {
        self.cachePolicy = NSURLRequestUseProtocolCachePolicy;
        self.timeoutInterval = 60.0;
        self.networkServiceType = NSURLNetworkServiceTypeDefault;
        self.allowsCellularAccess = YES;
        if (@available(iOS 13.0, *)) {
            self.allowsExpensiveNetworkAccess = YES;
        }
        if (@available(iOS 13.0, *)) {
            self.allowsConstrainedNetworkAccess = YES;
        }
        if (@available(iOS 14.5, *)) {
            self.assumesHTTP3Capable = NO;
        }
        if (@available(iOS 15.0, *)) {
            self.attribution = NSURLRequestAttributionDeveloper;
        }
    }
    return self;
}
- (void)setValuesWithRequest:(NSURLRequest *)request{
    self.url = request.URL.absoluteString;
    self.httpMethod = request.HTTPMethod.MKAPIHttpRequestMethod;
    [self.headersParam removeAll];
    self.headersParam.PS(request.allHTTPHeaderFields);
    self.HTTPBody = request.HTTPBody;
    self.HTTPBodyStream = request.HTTPBodyStream;
    
    self.cachePolicy = request.cachePolicy;
    self.timeoutInterval = request.timeoutInterval;
    self.networkServiceType = request.networkServiceType;
    self.allowsCellularAccess = request.allowsCellularAccess;
    if (@available(iOS 13.0, *)) {
        self.allowsExpensiveNetworkAccess = request.allowsCellularAccess;
    }
    if (@available(iOS 13.0, *)) {
        self.allowsConstrainedNetworkAccess = request.allowsConstrainedNetworkAccess;
    }
    if (@available(iOS 14.5, *)) {
        self.assumesHTTP3Capable = request.assumesHTTP3Capable;
    }
    if (@available(iOS 15.0, *)) {
        self.attribution = request.attribution;
    }
}
- (MKAPIDictionary *)headersParam{
    if(!_headersParam){
        _headersParam = [[MKAPIDictionary alloc] init];
    }
    return _headersParam;
}
- (id)copyWithZone:(NSZone *)zone{
    MKAPIRequestParam *obj = [[self.class alloc] init];
    obj.url = self.url;
    obj.httpMethod = self.httpMethod;
    obj.headersParam = [self.headersParam copy];
    obj.HTTPBody = [self.HTTPBody copy];
    obj.HTTPBodyStream = self.HTTPBodyStream;
    
    obj.cachePolicy = self.cachePolicy;
    obj.timeoutInterval = self.timeoutInterval;
    obj.networkServiceType = self.networkServiceType;
    obj.allowsCellularAccess = self.allowsCellularAccess;
    if (@available(iOS 13.0, *)) {
        obj.allowsExpensiveNetworkAccess = self.allowsExpensiveNetworkAccess;
    }
    if (@available(iOS 13.0, *)) {
        obj.allowsConstrainedNetworkAccess = self.allowsConstrainedNetworkAccess;
    }
    if (@available(iOS 14.5, *)) {
        obj.assumesHTTP3Capable = self.assumesHTTP3Capable;
    }
    if (@available(iOS 15.0, *)) {
        obj.attribution = self.attribution;
    }
    return obj;
}
- (NSString *)httpMethodString{
    return [NSString stringWithMKAPIHttpRequestMethod:self.httpMethod];
}
- (NSString *)description{
    NSString *desc = [NSString stringWithFormat:@"<%@:%p,url=%@,httpMethod=%@,headersParam:%@,contentType=%@>",NSStringFromClass(self.class),self,self.url,self.httpMethodString,self.headersParam.dictionary.mkapi_jsonString,self.contentType];
    return desc;
}
- (NSString *)contentType{
    return @"";
}
+ (BOOL)isHTTPMethodsEncodingParametersInURI:(MKAPIHttpRequestMethod)httpMethod{
    BOOL is = NO
    ||httpMethod==MKAPIHttpRequestMethodGET
    ||httpMethod==MKAPIHttpRequestMethodHEAD
    ||httpMethod==MKAPIHttpRequestMethodDELETE
    ;
    return is;
}
@end
@implementation NSString(MKAPIHttpRequestMethod)
+ (NSString *)stringWithMKAPIHttpRequestMethod:(MKAPIHttpRequestMethod)type{
    static NSDictionary *__shareMap__;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        __shareMap__ = @{
            @(MKAPIHttpRequestMethodGET):@"GET",
            @(MKAPIHttpRequestMethodPOST):@"POST",
            @(MKAPIHttpRequestMethodHEAD):@"HEAD",
            @(MKAPIHttpRequestMethodOPTIONS):@"OPTIONS",
            @(MKAPIHttpRequestMethodPUT):@"PUT",
            @(MKAPIHttpRequestMethodPATCH):@"PATCH",
            @(MKAPIHttpRequestMethodDELETE):@"DELETE",
            @(MKAPIHttpRequestMethodTRACE):@"TRACE",
            @(MKAPIHttpRequestMethodCONNECT):@"CONNECT",
        };
    });
    NSString *s = __shareMap__[@(type)]?:@"";
    return s;
}
- (MKAPIHttpRequestMethod)MKAPIHttpRequestMethod{
    static NSDictionary *__shareMap__;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        __shareMap__ = @{
            @"GET":@(MKAPIHttpRequestMethodGET),
            @"POST":@(MKAPIHttpRequestMethodPOST),
            @"HEAD":@(MKAPIHttpRequestMethodHEAD),
            @"OPTIONS":@(MKAPIHttpRequestMethodOPTIONS),
            @"PUT":@(MKAPIHttpRequestMethodPUT),
            @"PATCH":@(MKAPIHttpRequestMethodPATCH),
            @"DELETE":@(MKAPIHttpRequestMethodDELETE),
            @"TRACE":@(MKAPIHttpRequestMethodTRACE),
            @"CONNECT":@(MKAPIHttpRequestMethodCONNECT),
        };
    });
    NSNumber *r = __shareMap__[self.uppercaseString];
    return r!=nil?(MKAPIHttpRequestMethod)r.integerValue:MKAPIHttpRequestMethodPOST;
}
@end



@interface MKAPIRequestParamJSON ()
@property(nonatomic,strong) MKAPIDictionary *jsonParam;
@end

@implementation MKAPIRequestParamJSON
- (MKAPIDictionary *)jsonParam{
    if(!_jsonParam){
        _jsonParam = [[MKAPIDictionary alloc] init];
    }
    return _jsonParam;
}
- (id)copyWithZone:(NSZone *)zone{
    MKAPIRequestParamJSON *obj = [super copyWithZone:zone];
    obj.jsonParam = [obj.jsonParam copy];
    return obj;
}
- (NSString *)contentType{
    return @"application/json";
}
- (NSDictionary *)HTTPJsonBody{
    return self.jsonParam.dictionary;
}
- (NSString *)description{
    NSString *desc = [NSString stringWithFormat:@"<%@,jsonParam=%@>",[super description],self.jsonParam.dictionary.mkapi_jsonString];
    return desc;
}
@end

@implementation MKAPIRequestParamJSONArray
- (id)copyWithZone:(NSZone *)zone{
    MKAPIRequestParamJSONArray *obj = [super copyWithZone:zone];
    obj.jsonArrayParam = [obj.jsonArrayParam copy];
    return obj;
}
- (NSString *)description{
    NSString *desc = [NSString stringWithFormat:@"<%@,jsonArrayParam=%@>",[super description],self.jsonArrayParam];
    return desc;
}
@end



@interface MKAPIRequestParamForm ()
@property(nonatomic,strong) MKAPIDictionary *formParam;
@end
@implementation MKAPIRequestParamForm
- (MKAPIDictionary *)formParam{
    if(!_formParam){
        _formParam = [[MKAPIDictionary alloc] init];
    }
    return _formParam;
}
- (id)copyWithZone:(NSZone *)zone{
    MKAPIRequestParamForm *obj = [super copyWithZone:zone];
    obj.formParam = self.formParam.copy;
    return obj;
}
- (NSString *)contentType{
    return @"application/x-www-form-data-urlencoded";
}
- (NSDictionary *)HTTPJsonFormBody{
    return self.formParam.dictionary;
}
- (NSString *)description{
    NSString *desc = [NSString stringWithFormat:@"<%@,formParam=%@>",[super description],self.formParam.dictionary.mkapi_jsonString];
    return desc;
}
@end

@interface MKAPIRequestParamMultipartForm ()
@property(nonatomic,strong) MKAPIHttpFilesParam *filesParam;
@end
@implementation MKAPIRequestParamMultipartForm
- (MKAPIHttpFilesParam *)filesParam{
    if(!_filesParam){
        _filesParam = [[MKAPIHttpFilesParam alloc] init];
    }
    return _filesParam;
}
- (id)copyWithZone:(NSZone *)zone{
    MKAPIRequestParamMultipartForm *obj = [super copyWithZone:zone];
    obj.filesParam = self.filesParam.copy;
    return obj;
}
- (NSString *)contentType{
    return @"multipart/form-data";
}
- (NSString *)description{
    NSString *desc = [NSString stringWithFormat:@"<%@,filesParam=%@>",[super description],self.filesParam];
    return desc;
}
@end



@implementation MKAPIRequestParamOctetStream
- (NSString *)contentType{
    return @"application/octet-stream";
}
@end

@implementation MKAPIRequestParamOriginRequest : MKAPIRequestParam
- (void)setOriginRequest:(NSURLRequest *)originRequest{
    _originRequest = originRequest;
    [self setValuesWithRequest:originRequest];
}
- (NSString *)description{
    NSString *desc = [NSString stringWithFormat:@"<%@,originRequest=%@>",[super description],self.originRequest];
    return desc;
}
@end
